/**
 * Copyright (C) 2025 pony working team
 * SPDX-License-Identifier: MulanPSL-2.0
 */

#include <gtest/gtest.h>

#include "x_common.h"

class TestCommon : public ::testing::Test
{
protected:
    void SetUp() {};

    void TearDown() {};
};

TEST_F(TestCommon, offset_of)
{
    typedef struct s {
        char a;
        char b;
        // char r[2]; // reserve
        int c;
        long d;
        char e;
        // char r[1];
        short f;
        char g;
        // char r[3];
        int h;
    } s_t;

    EXPECT_EQ(offset_of(s_t, a), 0);
    EXPECT_EQ(offset_of(s_t, b), 1);
    EXPECT_EQ(offset_of(s_t, c), 4);
    EXPECT_EQ(offset_of(s_t, d), 8);
    EXPECT_EQ(offset_of(s_t, e), 16);
    EXPECT_EQ(offset_of(s_t, f), 18);
    EXPECT_EQ(offset_of(s_t, g), 20);
    EXPECT_EQ(offset_of(s_t, h), 24);
}

TEST_F(TestCommon, container_of)
{
    typedef struct s {
        char a;
        char b;
        int c;
    } s_t;

    s_t s1;

    char *pb = &s1.b;
    int *pc = &s1.c;

    EXPECT_EQ(container_of(pb, s_t, b), &s1);
    EXPECT_EQ(container_of(pc, s_t, c), &s1);
}

TEST_F(TestCommon, round_up)
{
    EXPECT_EQ(round_up(2, 4), 4);
    EXPECT_EQ(round_up(5, 4), 8);
    EXPECT_EQ(round_up(7, 8), 8);
    EXPECT_EQ(round_up(8, 8), 8);
    EXPECT_EQ(round_up(9, 8), 16);
    EXPECT_EQ(round_up(102, 8), 104);
}

TEST_F(TestCommon, round_down)
{
    EXPECT_EQ(round_down(2, 4), 0);
    EXPECT_EQ(round_down(5, 4), 4);
    EXPECT_EQ(round_down(7, 8), 0);
    EXPECT_EQ(round_down(8, 8), 8);
    EXPECT_EQ(round_down(9, 8), 8);
    EXPECT_EQ(round_down(102, 8), 96);
}

TEST_F(TestCommon, aligned_at)
{
    EXPECT_EQ(aligned_at(2, 4), false);
    EXPECT_EQ(aligned_at(4, 4), true);
    EXPECT_EQ(aligned_at(5, 4), false);
}

TEST_F(TestCommon, min)
{
    EXPECT_EQ(min(2, 4), 2);
    EXPECT_EQ(min(4, 4), 4);
    EXPECT_EQ(min(5, 4), 4);
}

TEST_F(TestCommon, max)
{
    EXPECT_EQ(max(2, 4), 4);
    EXPECT_EQ(max(4, 4), 4);
    EXPECT_EQ(max(5, 4), 5);
}

TEST_F(TestCommon, STATIC_ASSERT)
{
    STATIC_ASSERT(2 < 4);
    // STATIC_ASSERT(2 > 4);
}

TEST_F(TestCommon, ARRAY_SIZE)
{
    char a[5];
    int b[5];

    EXPECT_EQ(ARRAY_SIZE(a), 5);
    EXPECT_EQ(ARRAY_SIZE(b), 5);
}

TEST_F(TestCommon, __CONCAT)
{
    int ab = 4;
    int a_b = 5;

    EXPECT_EQ(__CONCAT(a, b), 4);
    EXPECT_EQ(__CONCAT(a, __CONCAT(_, b)), 5);
}

TEST_F(TestCommon, __CVTSTR)
{
    EXPECT_EQ(__CVTSTR(1), "1");
    EXPECT_EQ(__CVTSTR(-1), "-1");
    EXPECT_EQ(__CVTSTR(a), "a");
}
